/*
#####################################################################
####################	   T R I B U I T 		#####################
#####################################################################

Copyright (C) 2010  Christoph Schnack, Berlin (Germany)

This file is part of Tribuit.

    Tribuit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Tribuit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tribuit.  If not, see <http://www.gnu.org/licenses/>.


########################################################################
*/
package PDPictureEditor;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.filechooser.FileFilter;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.*;
import GuiTools.*;
import Mainframe.*;
import PictureDescription.*;
import Settings.*;

/**
 * @author Christoph Schnack
 *
 */
public class PictureEditorDialog implements PicturePanelParent {
	//file data
	PictureStorage PICSTO;
	PictureCollection colToEdit;
	String vocToEdit,title,pictureFilePath,titleInfoText="";
	PictureUnit puToEdit;
	//GUI-data
	MDTribuitFrame pedFrame;
	Mainframe MAINFRAME;
	Settings SET;
	Language LANG;
	MDManager PMDM;
	PicturePanel picturePanel;
	JFileChooser fileDialog;
	JPanel pnuPanel;
	JLabel modulesLabel;
	Vector<PNUComponent> pictureNameUnits;
	JCheckBox showAllTagsCB;
	boolean editMode=false,highlighting,highlightSwitch,vectorHighlightSwitch;
	int hlIndex=1;
	Timer flashTimer = new Timer(500,new TimerListener());
	Timer flashVectorTimer = new Timer(500,new FlashVectorTimerListener());
	JSpinner goToModuleSpinner;
	JComboBox collectionCB,zoomCB;
	TScrollPane westJsp;
	JPanel westPanel;
	SectionSelection sectionSelection;
	TribuitTextField nameTF,titleTF;
	Color panelBGC = Color.lightGray;
	String supportedFileFormats;
	
	public PictureEditorDialog(PictureStorage picsto,Settings set,Mainframe mf,MDManager pmdm,String vocabularyName,PictureUnit editPu){
		SET=set;
		LANG=SET.getLanguage();
		PICSTO=picsto;
		MAINFRAME=mf;
		PMDM=pmdm;
		vocToEdit=vocabularyName;
		colToEdit = PICSTO.getCollection(vocToEdit);
		
		puToEdit=editPu;
		title=LANG.getEditPicture();
		editMode=true;
		buildPED();
	}
	
	public PictureEditorDialog(PictureStorage picsto,Settings set,Mainframe mf,MDManager pmdm,String vocabularyName){
		SET=set;
		LANG=SET.getLanguage();
		PICSTO=picsto;
		MAINFRAME=mf;
		PMDM=pmdm;
		vocToEdit=vocabularyName;
		colToEdit = PICSTO.getCollection(vocToEdit);
		
		title=LANG.getCreatePicture();
		buildPED();
	}
	
	public void buildPED(){
		pedFrame=new MDTribuitFrame(title,PMDM);
		pictureNameUnits = new Vector<PNUComponent>();
		
		collectionCB = new JComboBox(PICSTO.getCollectionNames());
		collectionCB.setSelectedItem(vocToEdit);
		LabelPanel collectionCbLp = new LabelPanel(LANG.getCollection()+":",collectionCB);
		collectionCbLp.setPreferredSize(new Dimension(100,collectionCB.getHeight()));
		collectionCbLp.setOpaque(false);
		sectionSelection = new SectionSelection();
		LabelPanel sectionLp = new LabelPanel(LANG.getSection()+":",sectionSelection);
		sectionLp.setOpaque(false);
		nameTF = new TribuitTextField(SET,10);
		LabelPanel nameTfLp = new LabelPanel(LANG.getName()+":",nameTF);
		nameTfLp.setOpaque(false);
		JButton setPictureButton = new JButton(LANG.getChoose());
		setPictureButton.addActionListener(new SetPictureButtonListener());
		LabelPanel setPictureButtonLp = new LabelPanel(LANG.getPictureFile()+":",setPictureButton);
		setPictureButtonLp.setOpaque(false);
		
		pnuPanel = new JPanel();
		pnuPanel.setOpaque(false);
		
		JPanel tagModuleOptionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		tagModuleOptionsPanel.setOpaque(false);
		JButton addModuleBtn = new JButton(LANG.getAddModule());
		addModuleBtn.setToolTipText(LANG.getAddDescriptionModule());
		addModuleBtn.addActionListener(new AddModuleButtonListener());
		goToModuleSpinner = new JSpinner();
		goToModuleSpinner.setEnabled(false);
		goToModuleSpinner.addChangeListener(new ChangeListener(){
			public void stateChanged(ChangeEvent arg0) {
				pnuPanel.removeAll();
				int selection = ((Integer)goToModuleSpinner.getValue())-1;
				pnuPanel.add((PNUPanel)pictureNameUnits.elementAt(selection));
				pictureNameUnits.elementAt(selection).selectNothing();
				for(int i=0;i<pictureNameUnits.size();i++){
					if(i==selection)pictureNameUnits.elementAt(i).setHideTags(pictureNameUnits.elementAt(i).getShouldHideTags());
					else pictureNameUnits.elementAt(i).setHideTags(true);
				}
				customPack();
			}
			
		});
		modulesLabel = new JLabel("/0");
		tagModuleOptionsPanel.add(addModuleBtn);
		tagModuleOptionsPanel.add(new JLabel(LANG.getShowModule()+":"));
		tagModuleOptionsPanel.add(goToModuleSpinner);
		tagModuleOptionsPanel.add(modulesLabel);
		
		showAllTagsCB = new JCheckBox(LANG.getShowAllTags());
		showAllTagsCB.setEnabled(false);
		showAllTagsCB.setOpaque(false);
		showAllTagsCB.addActionListener(new ShowAllTagsCBListener());
		JPanel lowestPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		lowestPanel.setOpaque(false);
		lowestPanel.add(showAllTagsCB);
		
		JPanel tagPanel = new JPanel();
		tagPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black),LANG.getTags(),TitledBorder.ABOVE_TOP,TitledBorder.TOP,new Font(Font.SANS_SERIF,Font.BOLD,16)));
		tagPanel.setLayout(new GridBagLayout());
		GridBagConstraints tpGbc = new GridBagConstraints();
		tpGbc.fill = GridBagConstraints.BOTH;
		tpGbc.anchor = GridBagConstraints.NORTHWEST;
		tpGbc.weighty=5;
		tpGbc.weightx=1;
		tagPanel.add(pnuPanel,tpGbc);
		tpGbc.gridy = 1;
		tpGbc.weighty=0;
		tpGbc.insets = new Insets(2,10,0,0);
		tagPanel.add(tagModuleOptionsPanel,tpGbc);
		tpGbc.gridy = 2;
		tagPanel.add(lowestPanel,tpGbc);
		tagPanel.setPreferredSize(new Dimension(300,360));
		tagPanel.setBackground(panelBGC);
		
		picturePanel = new PicturePanel(SET,pedFrame,this);
		
		JPanel infoPanel = new JPanel();
		infoPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black),LANG.getFileProperties(),TitledBorder.ABOVE_TOP,TitledBorder.TOP,new Font(Font.SANS_SERIF,Font.BOLD,16)));
		infoPanel.setLayout(new GridBagLayout());
		GridBagConstraints iGbc = new GridBagConstraints();
		iGbc.fill = GridBagConstraints.BOTH;
		iGbc.anchor = GridBagConstraints.NORTHWEST;
		infoPanel.setBackground(panelBGC);
		iGbc.insets = new Insets(5,5,5,5);
		iGbc.gridy = 1;
		iGbc.gridx = 1;
		infoPanel.add(nameTfLp,iGbc);
		iGbc.gridx = 2;
		infoPanel.add(setPictureButtonLp,iGbc);
		iGbc.gridy = 2;
		iGbc.gridx = 1;
		infoPanel.add(collectionCbLp,iGbc);
		iGbc.gridx = 2;
		infoPanel.add(sectionLp,iGbc);
		
		JButton titleButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("infoIcon.png")));
		titleButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				titleInfoText=InfoText.getInfoText(SET, pedFrame, titleInfoText, LANG.getTitleInfoText());
			}
		});
		titleButton.setToolTipText(LANG.getTitleInfoText());
		titleTF = new TribuitTextField(SET,10);
		JPanel titleLpPanel=  new JPanel();
		titleLpPanel.add(titleTF);
		titleLpPanel.add(titleButton);
		titleLpPanel.setOpaque(false);
		JPanel titlePanel = new JPanel();
		titlePanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black),LANG.getTitle(),TitledBorder.ABOVE_TOP,TitledBorder.TOP,new Font(Font.SANS_SERIF,Font.BOLD,16)));
		titlePanel.setBackground(panelBGC);
		titlePanel.add(titleLpPanel);
		
		JPanel zoomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		JLabel zoomLabel = new JLabel("zoom:");
		zoomLabel.setOpaque(false);
		zoomCB = new JComboBox(GuiTools.getZOOMSTEPS());
		zoomCB.setSelectedItem("1.00");
		zoomCB.addActionListener(new ZoomListener());
		zoomCB.setEnabled(false);
		zoomPanel.add(zoomLabel);
		zoomPanel.add(zoomCB);
		zoomPanel.setOpaque(false);
		
		westPanel = new JPanel();
		westPanel.setLayout(new GridBagLayout());
		GridBagConstraints gb = new GridBagConstraints();
		gb.anchor = GridBagConstraints.NORTHWEST;
		gb.fill = GridBagConstraints.BOTH;
		gb.weighty = 1;
		gb.insets = new Insets(20,20,0,20);
		westPanel.add(infoPanel,gb);
		gb.gridy=1;
		gb.insets = new Insets(10,20,0,20);
		westPanel.add(titlePanel,gb);
		gb.gridy=2;
		westPanel.add(tagPanel,gb);
		gb.insets = new Insets(10,20,20,20);
		gb.gridy=3;
		westPanel.add(zoomPanel,gb);
		westPanel.setBackground(Color.gray);
		
		westJsp = new TScrollPane(westPanel);
		westJsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		
		JPanel buttonPanel = new JPanel();
		JButton okButton = new JButton("ok");
		okButton.addActionListener(new OkListener());
		JButton cancelButton = new JButton(LANG.getCancel());
		cancelButton.addActionListener(new CancelListener());
		buttonPanel.add(okButton);
		buttonPanel.add(cancelButton);
		buttonPanel.setBackground(GuiTools.BGCOLOR);
		
		pedFrame.getContentPane().add(BorderLayout.NORTH,new Header(title));
		pedFrame.getContentPane().add(BorderLayout.WEST,westJsp);
		pedFrame.getContentPane().add(BorderLayout.CENTER,picturePanel);
		pedFrame.getContentPane().add(BorderLayout.SOUTH,buttonPanel);
		pedFrame.setResizable(true);
		
		StringBuffer sb = new StringBuffer();
		String[] fileFormats = ImageIO.getReaderFormatNames();
		for(String fileFormat : fileFormats){
			sb.append("*."+fileFormat+"; ");
		}
		supportedFileFormats = sb.toString();
		pedFrame.showUp(200, 50);
		pedFrame.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				new PictureVocabularyManageDialog(PICSTO,SET,MAINFRAME,PMDM,vocToEdit);
			}
		});
		if(editMode){
			setUp();
		}
	}
	
	
	public void setUp(){
		zoomCB.setEnabled(true);
		nameTF.setText(puToEdit.getName());
		sectionSelection.setSection(puToEdit.getSection());
		titleTF.setText(puToEdit.getTitle());
		titleInfoText = puToEdit.getTitleInfo();
		if(puToEdit.hasPictureNameUnits()){
			Vector<PictureNameUnit> units = puToEdit.getTags();
			PictureNameUnit newPNU,unit;
			Vector<PictureTagUnit> tags,oldTags;
			PictureTagUnit ptu;
			Vector<TADE> tades,oldTades;
			TADE tade;
			for(int i = 0;i<units.size();i++){
				unit = units.elementAt(i);
				tags = new Vector<PictureTagUnit>();
				if(unit.hasTags()){
					oldTags = unit.getTags();
					for(int r = 0;r<oldTags.size();r++){
						ptu = oldTags.elementAt(r);
						tades = new Vector<TADE>();
						if(ptu.hasTADEs()){
							oldTades = ptu.getPictureTags();
							for(int t = 0;t<oldTades.size();t++){
								tade = oldTades.elementAt(t);
								Color col = tade.getColor(),hlCol = tade.getFlashColor();
								tades.add(new TADE(tade.getType(),new Point(tade.getPoint().x,tade.getPoint().y),new Color(col.getRed(),col.getGreen(),col.getBlue()),new Color(hlCol.getRed(),hlCol.getGreen(),hlCol.getBlue())));
							}
						}
						Point p = new Point(ptu.getCenterPosition().x,ptu.getCenterPosition().y);
						Color col=ptu.getColor(),bgCol=ptu.getBgColor(),hlCol=ptu.getBgHlColor();
						tags.add(new PictureTagUnit(tades,p,new Color(col.getRed(),col.getGreen(),col.getBlue()),new Color(bgCol.getRed(),bgCol.getGreen(),bgCol.getBlue()),new Color(hlCol.getRed(),hlCol.getGreen(),hlCol.getBlue()),ptu.getRadius()));
					}
				}
				newPNU = new PictureNameUnit(unit.getName(),unit.getInfoText(),tags);
				pictureNameUnits.add(new PNUPanel(i,newPNU));
			}
			pnuPanel.add((PNUPanel)pictureNameUnits.elementAt(0));
			setPictureNameUnitPanels();
		}
		picturePanel.setImage(GuiTools.loadImage(GuiTools.PATHTOPICTUREMAPS+File.separator+colToEdit.getName()+File.separator+puToEdit.getName()+File.separator+"image"));
		if(pictureNameUnits.size()>0){
			for(int i=0;i<pictureNameUnits.size();i++){
				pictureNameUnits.elementAt(i).setAddTagButtonActive(true);
				pictureNameUnits.elementAt(i).setHideTags(true);
			}
			pictureNameUnits.elementAt(0).setHideTags(false);
			picturePanel.repaintImagePanel();
		}
	}
	
	
	public void showFileDialog(){
		fileDialog = new JFileChooser();
		fileDialog.setDialogTitle(LANG.getChoosePictureFile());
		fileDialog.setFileFilter(new FileFilter(){
			public boolean accept(File file){
				String name=file.getName().toLowerCase();
				String[] fileFormats = ImageIO.getReaderFormatNames();
				if(file.isDirectory())return true;
				for(String fileFormat : fileFormats){
					if(name.endsWith(fileFormat)) return true;
				}
				return false;
			}
			public String getDescription() {
				return "Pictures ("+supportedFileFormats+")";
			}
		});
		fileDialog.showDialog(pedFrame,LANG.getLoad());
		File f = fileDialog.getSelectedFile();
		if(f!=null){
			String oldPath = pictureFilePath;
			pictureFilePath = f.getAbsolutePath();
			if(pictureFilePath!=null){
				try{
					Image img = ImageIO.read(new File(pictureFilePath));
					if(img!=null){
						picturePanel.setImage(img);
						zoomCB.setEnabled(true);
						if(pictureNameUnits.size()>0){
							for(int i=0;i<pictureNameUnits.size();i++){
								pictureNameUnits.elementAt(i).setAddTagButtonActive(true);
							}
						}
					}
					else{
						pictureFilePath = oldPath;
						JOptionPane.showMessageDialog(pedFrame,LANG.getUnsupportedFileFormat()+":\n"+supportedFileFormats,LANG.getAttention(),JOptionPane.ERROR_MESSAGE);
					}
				}
				catch(Exception e){e.printStackTrace();}
			}
		}
	}
	
	class ZoomListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			picturePanel.setZoom(Double.parseDouble((String)zoomCB.getSelectedItem()));
		}
	}
	
	public void decreaseZoom(){
		int ind = zoomCB.getSelectedIndex();
		if(ind>0){
			zoomCB.setSelectedIndex(--ind);
			picturePanel.setZoom(Double.parseDouble((String)zoomCB.getSelectedItem()));
		}
	}
	
	class SetPictureButtonListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			showFileDialog();
		}
	}
	
	class PNUPanel extends JPanel implements PNUComponent{
		TribuitTextField tagNameTF;
		Vector<PictureTagUnit> positions;
		String infoText="";
		PNUPanel thisPanel;
		int index,selectedTag=-1,maximumTagSelection=0;
		JButton addTagButton,delTagButton, editTagButton, selectTagUpButton, selectTagDownButton,delVectorButton, editVectorButton, selectVectorUpButton, selectVectorDownButton,addTagArmButton;
		JLabel selectedTagLabel,selectedVectorLabel;
		JCheckBox hideTagsCB;
		TagArmPanel tagArmPanel;
		boolean hideTags=false;
		
		public PNUPanel(int ind,PictureNameUnit pnu){
			this(ind);
			tagNameTF.setText(pnu.getName());
			infoText = pnu.getInfoText();
			positions = pnu.getTags();
			maximumTagSelection=positions.size()-1;
			selectTagUpButton.setEnabled(true);
			updateTagLabel();
		}
		
		public PNUPanel(int ind){
			super();
			thisPanel=this;
			setIndex(ind);
			positions = new Vector<PictureTagUnit>();
			tagNameTF = new TribuitTextField(SET,10);
			tagNameTF.addFocusListener(new FocusListener(){
				public void focusGained(FocusEvent e){
					highlightTags(index);
				}
				public void focusLost(FocusEvent e){
					stopHighlightTags();
				}
			});
			JButton editInfoButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("infoIcon.png")));
			editInfoButton.addActionListener(new EIButtonListener());
			addTagButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("createTag.png")));
			addTagButton.setToolTipText(LANG.getAddTag());
			addTagButton.addActionListener(new AddTagButtonListener());
			addTagButton.setEnabled((editMode)?true:pictureFilePath!=null);
			delTagButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("deleteIcon.png")));
			delTagButton.setToolTipText(LANG.getDeleteTag());
			delTagButton.addActionListener(new DelTagButtonListener());
			delTagButton.setEnabled(false);
			editTagButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("editIcon.png")));
			editTagButton.setToolTipText(LANG.getEditTag());
			editTagButton.addActionListener(new EditTagButtonListener());
			editTagButton.setEnabled(false);
			addTagArmButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("newArmIcon.png")));
			addTagArmButton.setToolTipText(LANG.getAddTagAreaDefiningElement());
			addTagArmButton.setEnabled(false);
			addTagArmButton.addActionListener(new AddTagArmButtonListener());
			selectTagUpButton = new JButton(">");
			selectTagUpButton.addActionListener(new SelectTagUpButtonListener());
			selectTagUpButton.setEnabled(false);
			selectTagDownButton = new JButton("<");
			selectTagDownButton.addActionListener(new SelectTagDownButtonListener());
			selectTagDownButton.setEnabled(false);
			selectedTagLabel = new JLabel("-/"+positions.size());
			JPanel selectPanel = new JPanel();
			selectPanel.add(selectTagDownButton);
			selectPanel.add(selectedTagLabel);
			selectPanel.add(selectTagUpButton);
			selectPanel.add(editTagButton);
			selectPanel.add(delTagButton);
			selectPanel.add(addTagArmButton);
			selectPanel.setOpaque(false);
			
			tagArmPanel = new TagArmPanel();
			
			JPanel tagPanel = new JPanel();
			tagPanel.setOpaque(false);
			tagPanel.setLayout(new BoxLayout(tagPanel,BoxLayout.Y_AXIS));
			LabelPanel selectTagLP = new LabelPanel(LANG.getSelectTag()+":",selectPanel);
			selectTagLP.setOpaque(false);
			LabelPanel tagArmLP = new LabelPanel(LANG.getSelectArm()+":",tagArmPanel);
			tagArmLP.setOpaque(false);
			tagPanel.add(selectTagLP);
			tagPanel.add(tagArmLP);
			
			JButton deletePanelBtn = new JButton(LANG.getDeleteThisModule());
			deletePanelBtn.addActionListener(new DelButtonListener());
			
			hideTagsCB = new JCheckBox(LANG.getHideTags(),false);
			hideTagsCB.setOpaque(false);
			hideTagsCB.addActionListener(new HideTagsListener());
			
			JPanel textPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
			textPanel.add(tagNameTF);
			textPanel.add(editInfoButton);
			textPanel.add(addTagButton);
			textPanel.setOpaque(false);
			thisPanel.setLayout(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.fill=GridBagConstraints.HORIZONTAL;
			gbc.anchor=GridBagConstraints.NORTHWEST;
			gbc.weighty=1;
			thisPanel.add(textPanel,gbc);
			gbc.gridy=1;
			thisPanel.add(tagPanel,gbc);
			gbc.fill=GridBagConstraints.NONE;
			gbc.gridy=2;
			thisPanel.add(hideTagsCB,gbc);
			gbc.gridy=3;
			thisPanel.add(deletePanelBtn,gbc);
			thisPanel.setOpaque(false);
		}
		
		public void setIndex(int ind){
			TitledBorder tb = BorderFactory.createTitledBorder(""+(ind+1));
			tb.setTitleFont(new Font(Font.SANS_SERIF,Font.BOLD,15));
			thisPanel.setBorder(tb);
			index=ind;
		}
		public int getIndex(){
			return index;
		}
		
		public String getTagName(){
			return tagNameTF.getText().trim();
		}
		
		public String getTagInfo(){
			return infoText;
		}
		
		public Vector<PictureTagUnit> getPictureTags(){
			return positions;
		}
		
		public void addPictureTagUnit(PictureTagUnit pt){
			positions.add(pt);
			maximumTagSelection=positions.size()-1;
			selectTagUpButton.setEnabled(true);
			updateTagLabel();
			picturePanel.reset();
		}
		
		public void setPictureTagUnit(int tagIndex,PictureTagUnit newUnit){
			tagArmPanel.updatePanel();
			positions.set(tagIndex,newUnit);
		}
		
		public void updateTagLabel(){
			selectedTagLabel.setText(((selectedTag==-1)?"-":selectedTag+1)+"/"+positions.size());
		}
		
		public boolean hasTags(){
			return positions.size()>0;
		}
		
		public int getMarkTagIndex(){
			return selectedTag;
		}
		
		public void disableDeleteTagButton(){
			delTagButton.setEnabled(false);
			editTagButton.setEnabled(false);
			addTagArmButton.setEnabled(false);
			tagArmPanel.disablePanel();
		}
		
		public void selectNothing(){
			disableDeleteTagButton();
			selectTagDownButton.setEnabled(false);
			selectedTag = -1;
			updateTagLabel();
			picturePanel.reset();
			picturePanel.disableMarkTag();
			picturePanel.repaintImagePanel();
		}
		
		public void disableArmPanel(){
			tagArmPanel.disablePanel();
		}
		
		public void hideTags(boolean hide){
			if((hide&&!hideTags) || (!hide&&hideTags))hideTagsCB.doClick();
		}
		
		public boolean getHideTags(){
			return hideTags;
		}
		
		public boolean getShouldHideTags(){
			return hideTagsCB.isSelected();
		}
		
		public void setHideTags(boolean arg){
			hideTags = arg;
		}
		
		public void setAddTagButtonActive(boolean arg){
			addTagButton.setEnabled(arg);
		}
		
		public void updateTagArmPanel(){
			tagArmPanel.updatePanel();
		}
		
		class TagArmPanel extends JPanel{
			int selectedArm=-1,maxSelection=-1;
			JLabel label;
			JButton upButton, downButton,editButton,deleteButton;
			public TagArmPanel(){
				super();
				this.setLayout(new FlowLayout(FlowLayout.LEFT));
				label = new JLabel("-/-");
				upButton = new JButton(">");
				upButton.addActionListener(new UpBtnListener());
				downButton = new JButton("<");
				downButton.addActionListener(new DownBtnListener());
				editButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("editIcon.png")));
				editButton.addActionListener(new EditBtnListener());
				deleteButton = new JButton(new ImageIcon(GuiTools.loadImageFromGraphics("deleteIcon.png")));
				deleteButton.addActionListener(new DeleteBtnListener());
				this.add(downButton);
				this.add(label);
				this.add(upButton);
				this.add(editButton);
				this.add(deleteButton);
				this.setOpaque(false);
				upButton.setEnabled(false);
				downButton.setEnabled(false);
				editButton.setEnabled(false);
				deleteButton.setEnabled(false);
				updateLabel();
			}
			
			public void disablePanel(){
				stopHighlightVector();
				selectedArm=-1;
				maxSelection = -1;
				upButton.setEnabled(false);
				downButton.setEnabled(false);
				editButton.setEnabled(false);
				deleteButton.setEnabled(false);
				updateLabel();
			}
			
			public void updatePanel(){
				disablePanel();
				if(selectedTag>-1){
					if(positions.elementAt(selectedTag).getPictureTags().size()>0){
						upButton.setEnabled(true);
						maxSelection = positions.elementAt(selectedTag).getPictureTags().size()-1;
					}
				}
				updateLabel();
			}
			
			private void updateLabel(){
				label.setText(((selectedArm==-1)?"-":(selectedArm+1))+"/"+(maxSelection+1));
			}
			
			class UpBtnListener implements ActionListener{
				public void actionPerformed(ActionEvent e){
					if(selectedArm<maxSelection) startHighlightVector(++selectedArm);
					if(selectedArm==maxSelection)upButton.setEnabled(false);
					if(selectedArm>0) downButton.setEnabled(true);
					editButton.setEnabled(true);
					deleteButton.setEnabled(true);
					updateLabel();
				}
			}
			
			class DownBtnListener implements ActionListener{
				public void actionPerformed(ActionEvent e){
					if(selectedArm>0){
						stopHighlightVector();
						startHighlightVector(--selectedArm);
					}
					if(selectedArm<maxSelection) upButton.setEnabled(true);
					if(selectedArm==0) downButton.setEnabled(false);
					updateLabel();
				}
			}
			
			class EditBtnListener implements ActionListener{
				public void actionPerformed(ActionEvent e){
					picturePanel.editTade(selectedTag,selectedArm,positions.elementAt(selectedTag).getPictureTags().elementAt(selectedArm));
				}
			}
			
			class DeleteBtnListener implements ActionListener{
				public void actionPerformed(ActionEvent e){
					stopHighlightVector();
					positions.elementAt(selectedTag).deleteTADEAt(selectedArm);
					picturePanel.repaintImagePanel();
					updatePanel();
				}
			}
		}
		
		class DelButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				int answer = JOptionPane.showConfirmDialog(pedFrame, LANG.getReallyDeleteThisModule(), LANG.getAttention(), JOptionPane.WARNING_MESSAGE);
				if(answer==JOptionPane.YES_OPTION){
					pictureNameUnits.remove(thisPanel.getIndex());
					pnuPanel.removeAll();
					setPictureNameUnitPanels();
					if(pictureNameUnits.size()>0){
						int selection = ((Integer)goToModuleSpinner.getValue())-1;
						for(int i=0;i<pictureNameUnits.size();i++){
							if(i==selection)pictureNameUnits.elementAt(i).setHideTags(pictureNameUnits.elementAt(i).getShouldHideTags());
							else pictureNameUnits.elementAt(i).setHideTags(true);
						}
						pnuPanel.add((PNUPanel)pictureNameUnits.elementAt(selection));
					}
					customPack();
					picturePanel.reset();
				}
			}
		}
		
		class SelectTagUpButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				for(int i=0;i<pictureNameUnits.size();i++){
					pictureNameUnits.elementAt(i).disableDeleteTagButton();
				}
				if(!(selectedTag==maximumTagSelection))selectedTag++;
				picturePanel.reset();
				picturePanel.enableMarkTag(index,selectedTag);
				delTagButton.setEnabled(true);
				editTagButton.setEnabled(true);
				addTagArmButton.setEnabled(true);
				tagArmPanel.updatePanel();
				selectedTagLabel.setText(""+(selectedTag+1)+"/"+positions.size());
				if(maximumTagSelection>0 && selectedTag>0 ) selectTagDownButton.setEnabled(true);
				picturePanel.repaintImagePanel();
			}
		}
		
		class SelectTagDownButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				selectedTag--;
				tagArmPanel.updatePanel();
				picturePanel.reset();
				picturePanel.enableMarkTag(index,selectedTag);
				delTagButton.setEnabled(true);
				editTagButton.setEnabled(true);
				selectedTagLabel.setText(""+(selectedTag+1)+"/"+positions.size());
				if(selectedTag==0) selectTagDownButton.setEnabled(false);
				picturePanel.repaintImagePanel();
			}
		}
		
		class EIButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				infoText = InfoText.getInfoText(SET,pedFrame,infoText,"Infotext "+LANG.getTag()+" "+(index+1));
			}
		}
		
		class AddTagArmButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				picturePanel.createTagArmDialog(index, selectedTag, positions.elementAt(selectedTag));
			}
		}
		
		class AddTagButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				picturePanel.setTag(true);
				picturePanel.setTagIndex(index);
			}
		}
		class DelTagButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				positions.remove(selectedTag);
				maximumTagSelection=positions.size()-1;
				selectedTag=-1;
				selectedTagLabel.setText("-/"+positions.size());
				picturePanel.disableMarkTag();
				picturePanel.repaintImagePanel();
				delTagButton.setEnabled(false);
				editTagButton.setEnabled(false);
				selectTagDownButton.setEnabled(false);
				addTagArmButton.setEnabled(false);
				if(positions.size()==0){
					selectTagUpButton.setEnabled(false);
				}
				tagArmPanel.updatePanel();
			}
		}
		
		class EditTagButtonListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				picturePanel.createTagDialog(index, selectedTag, positions.get(selectedTag));
			}
		}
		
		private class HideTagsListener implements ActionListener{
			public void actionPerformed(ActionEvent e){
				hideTags = hideTagsCB.isSelected();
				picturePanel.repaintImagePanel();
			}
		}
	}
	
	public void addPictureTagUnitTo(PictureTagUnit ptu,int index){
		pictureNameUnits.elementAt(index).addPictureTagUnit(ptu);
	}
	/**
	 * Replaces a PictureTagUnit
	 * @param index of PictureNameUnit
	 * @param tagInd index of PictureTagUnit
	 * @param ptu new PictureTagUnit
	 */
	public void setPictureTagUnit(int index, int tagInd,PictureTagUnit ptu){
		pictureNameUnits.elementAt(index).setPictureTagUnit(tagInd,ptu);
	}
	public void setTagArm(int ind,int tagInd,int armInd,TADE tade){
		pictureNameUnits.elementAt(ind).getPictureTags().elementAt(tagInd).replaceTade(armInd,tade);
		pictureNameUnits.elementAt(ind).updateTagArmPanel();
	}
	public Vector<PNUComponent> getPictureNameUnits(){
		return pictureNameUnits;
	}
	
	public boolean getShowAllTags(){
		return showAllTagsCB.isSelected();
	}
	
	public void highlightTags(int index){
		hlIndex=index;
		highlighting=true;
		picturePanel.setHighlighting(true);
		picturePanel.setHlIndex(hlIndex);
		if(flashVectorTimer.isRunning()){
			flashVectorTimer.stop();
			picturePanel.setHighlightVector(true);
		}
		flashTimer.start();
	}
	class TimerListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			highlightSwitch=highlightSwitch?false:true;
			picturePanel.setHighlightSwitch(highlightSwitch?false:true);
			picturePanel.repaintImagePanel();
		}
	}
	
	public void stopHighlightTags(){
		flashTimer.stop();
		picturePanel.setHighlighting(false);
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				picturePanel.repaintImagePanel();
				if(picturePanel.getHighlightVector()){
					flashVectorTimer.start();
				}
			}
		});
	}
	
	public void startHighlightVector(int vIndex){
		picturePanel.setHighlightVector(true);
		picturePanel.setHighlightVectorNumber(vIndex);
		flashVectorTimer.start();
	}
	
	public void stopHighlightVector(){
		flashVectorTimer.stop();
		picturePanel.setHighlightVector(false);
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				picturePanel.repaintImagePanel();
			}
		});
	}
	
	class FlashVectorTimerListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			vectorHighlightSwitch=(vectorHighlightSwitch)?false:true;
			picturePanel.setHighlightVector(vectorHighlightSwitch);
			picturePanel.repaint();
		}
	}
	
	
	class AddModuleButtonListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			int index = pictureNameUnits.size();
			if(index<99){
				pictureNameUnits.add(new PNUPanel(index));
				if(pictureNameUnits.size()==1) pnuPanel.add((PNUPanel)pictureNameUnits.elementAt(0));
				setPictureNameUnitPanels();
			}
			else{
				JOptionPane.showMessageDialog(pedFrame,LANG.getModulesMax(),LANG.getAttention(),JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	public void setPictureNameUnitPanels(){
		if(pictureNameUnits.size()>0){
			for(int i=0;i<pictureNameUnits.size();i++){
				pictureNameUnits.elementAt(i).setIndex(i);
			}
			goToModuleSpinner.setEnabled(true);
			showAllTagsCB.setEnabled(true);
			int val = (Integer)goToModuleSpinner.getValue();
			if(val>pictureNameUnits.size()) val--;
			goToModuleSpinner.setModel(new SpinnerNumberModel((val==0)?1:val,1,pictureNameUnits.size(),1));
		}
		else{
			pnuPanel.removeAll();
			goToModuleSpinner.setEnabled(false);
			showAllTagsCB.setEnabled(false);
		}
		modulesLabel.setText("/"+pictureNameUnits.size());
		customPack();
	}
	
	class ShowAllTagsCBListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			picturePanel.repaintImagePanel();
		}
	}
	
	public boolean hasTags(){
		if(pictureNameUnits.size()>0){
			for(int i=0;i<pictureNameUnits.size();i++){
				if(pictureNameUnits.elementAt(i).hasTags()) return true;
			}
			return false;
		}
		else return false;
	}
	
	class OkListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			String collection = (String) collectionCB.getSelectedItem();
			String section = sectionSelection.getSelection();
			String name = nameTF.getText().trim();
			String title = titleTF.getText().trim();
			boolean hasTags = hasTags();
			
			if(!editMode && pictureFilePath==null){
				JOptionPane.showMessageDialog(pedFrame,LANG.getPleaseSelectPictureFile(),LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
				return;
			}
			if(name.equals("") || ! GuiTools.checkInput(name)){
				GuiTools.showEmptyOrInvalidInputWarning(LANG, pedFrame, LANG.getName());
				return;
			}
			else{
				if(!editMode && colToEdit.hasPicture(name)){
					JOptionPane.showMessageDialog(pedFrame,LANG.getError().toUpperCase()+" ("+LANG.getTextField()+": "+LANG.getName()+"):\n"+LANG.getNameExistsAlreadyInThisCollection(),LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
					return;
				}
			}
			if(section==null || section.equals("")){
				int choice = JOptionPane.showConfirmDialog(pedFrame,LANG.getWithoutLection(),LANG.getAttention(),JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
				if(choice==JOptionPane.NO_OPTION)return;
				else section = LANG.getUnknown();
			}
			else{
				if(!GuiTools.checkInput(section)){
					JOptionPane.showMessageDialog(pedFrame,LANG.getError().toUpperCase()+" ("+LANG.getTextField()+": "+LANG.getSection()+"):\n"+LANG.getNotThoseSigns()+": "+GuiTools.NOTALLOWEDSIGNS,LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
					return;
				}
			}
			if(!GuiTools.checkInput(titleInfoText)){
				JOptionPane.showMessageDialog(pedFrame,LANG.getError().toUpperCase()+" ("+LANG.getTitleInfoText()+"):\n"+LANG.getNotThoseSigns()+": "+GuiTools.NOTALLOWEDSIGNS,LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
				return;
			}
			if(!hasTags && title.equals("") ){
				JOptionPane.showMessageDialog(pedFrame,LANG.getSetTitleAndOrTags(),LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
				return;
			}
			if(!title.equals("")&&!GuiTools.checkInput(title)){
				JOptionPane.showMessageDialog(pedFrame,LANG.getError().toUpperCase()+" ("+LANG.getTextField()+": "+LANG.getTitle()+"):\n"+LANG.getNotThoseSigns()+": "+GuiTools.NOTALLOWEDSIGNS,LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
				return;
			}
			Vector<PictureNameUnit> units = new Vector<PictureNameUnit>();
			if(hasTags){
				for(int i=0;i<pictureNameUnits.size();i++){
					PNUPanel pnu = (PNUPanel)pictureNameUnits.elementAt(i);
					if(pnu.getTagName().equals("") || ! GuiTools.checkInput(pnu.getTagName())){
						GuiTools.showEmptyOrInvalidInputWarning(LANG, pedFrame, LANG.getTagName()+" ("+LANG.getTagModule()+": "+(i+1)+")");
						return;
					}
					if(!pnu.hasTags()){
						JOptionPane.showMessageDialog(pedFrame,LANG.getError().toUpperCase()+" ("+LANG.getTagModule()+" "+(i+1)+"):\n"+LANG.getPleaseSetTags(),LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
						return;
					}
					else{
						if(!GuiTools.checkInput(pnu.getTagInfo())){
							JOptionPane.showMessageDialog(pedFrame,LANG.getError().toUpperCase()+" ("+LANG.getTagModule()+" "+(i+1)+" "+LANG.getTagInfoText()+"):\n"+LANG.getNotThoseSigns()+": "+GuiTools.NOTALLOWEDSIGNS,LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
							return;
						}
						else{
							units.add(new PictureNameUnit(pnu.getTagName(),pnu.getTagInfo(),pnu.getPictureTags()));
						}
					}
				}
			}
			PictureUnit pu = new PictureUnit(name,title,titleInfoText,section,units);
			if(editMode){
				if(!puToEdit.getName().equals(name) || !collection.equals(colToEdit.getName())){
					if((!collection.equals(colToEdit.getName())?PICSTO.getCollection(collection).hasPicture(name):colToEdit.hasPicture(name))){
						JOptionPane.showMessageDialog(pedFrame,LANG.getError().toUpperCase()+" ("+LANG.getTextField()+": "+LANG.getName()+"):\n"+LANG.getNameExistsAlreadyInThisCollection(),LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
						return;
					}
					else{
						pictureFilePath = GuiTools.PATHTOPICTUREMAPS+File.separator+colToEdit.getName()+File.separator+puToEdit.getName()+File.separator+"image";
						PICSTO.createPUToVoc(pu,pictureFilePath,collection);
						PICSTO.deletePictureUnitInCollection(puToEdit.getName(),colToEdit.getName());
					}
				}
				else{
					PICSTO.editPictureUnitInCollection(pu,pictureFilePath,colToEdit.getName());
				}
				PICSTO.alterUnitNameInLessons(colToEdit.getName(),puToEdit.getName(), collection, name);
			}
			else{
				PICSTO.createPUToVoc(pu,pictureFilePath,collection);
			}
			pedFrame.dispose();
			new PictureVocabularyManageDialog(PICSTO,SET,MAINFRAME,PMDM,vocToEdit);
		}
	}
	
	class CancelListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			pedFrame.dispose();
			System.gc();
			new PictureVocabularyManageDialog(PICSTO,SET,MAINFRAME,PMDM,vocToEdit);
		}
	}
	
	class SectionSelection extends JPanel{
		String selections;
		JComboBox sectionCB;
		
		public SectionSelection(String name){
			this();
			sectionCB.setSelectedItem(name);
		}
		
		public SectionSelection(){
			super();
			Vector<String> sects = colToEdit.getSections();
			if(sects.size()==0 || !sects.contains(LANG.getUnknown())) sects.add(LANG.getUnknown());
			sectionCB = new JComboBox(sects);
			sectionCB.setPreferredSize(new Dimension(100,sectionCB.getHeight()));
			JButton newRB = new JButton("+");
			newRB.setToolTipText(LANG.getCreateSection());
			newRB.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					String input = JOptionPane.showInputDialog(pedFrame,LANG.getInsertNewSectionName());
					if(input!=null){
						input = input.trim();
						if(!input.equals("")){
							sectionCB.addItem(input);
						}
					}
				}
			});

			sectionCB.setOpaque(false);
			this.setLayout(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.anchor = GridBagConstraints.NORTHWEST;
			gbc.fill = GridBagConstraints.BOTH;
			gbc.gridy=1;
			gbc.gridx=1;
			this.add(sectionCB,gbc);
			gbc.gridx=2;
			this.add(newRB,gbc);
			this.setOpaque(false);
		}
		
		public String getSelection(){
			return (String) sectionCB.getSelectedItem();
		}
		
		public void setSection(String arg){
			sectionCB.setSelectedItem(arg);
		}
	}
	
	
	public void customPack(){
		pedFrame.setPreferredSize(new Dimension(pedFrame.getWidth(),pedFrame.getHeight()));
		pedFrame.pack();
		pedFrame.repaint();
	}
	
}


